<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>HTML Live Preview</title>
  <style>
  * {
    box-sizing: border-box;
  }

  body {
    margin: 0;
    padding: 0;
    font-family: Arial, sans-serif;
    height: 100vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .container {
    display: flex;
    flex-direction: column;
    height: calc(100vh - 60px);
    width: 100%;
  }

  .editor-container, .preview-container {
    flex: 1;
    overflow: hidden;
    position: relative;
  }

  .editor {
    width: 100%;
    height: 100%;
    resize: none;
    padding: 10px;
    border: none;
    border-bottom: 1px solid #ccc;
    font-size: 16px;
    font-family: monospace;
    background-color: #def;
  }

  .preview {
    width: 100%;
    height: 100%;
    border: none;
    background-color: white;
    overflow: auto;
  }

  .navbar {
    height: auto;
    min-height: 75px;
    background-color: #2c3e50;
    display: flex;
    align-items: center;
    padding: 16px 24px;
    border-bottom: 1px solid #34495e;
  }

  .title {
    margin: 0;
    flex: 1;
    color: #ffffff;
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: 0.5px;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  }

  .button-group {
    display: flex;
    gap: 10px;
  }

  .toggle-button, .copy-button {
    background-color: #3498db;
    color: white;
    border: none;
    padding: 8px 16px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.3px;
    transition: all 0.2s ease;
  }

  .toggle-button:hover, .copy-button:hover {
    opacity: 0.9;
  }

  .copy-button {
    background-color: #27ae60;
  }

  .copy-button:active, .toggle-button:active {
    transform: translateY(1px);
  }

  .copy-notification {
    position: fixed;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    background-color: rgba(0, 0, 0, 0.8);
    color: white;
    padding: 10px 20px;
    border-radius: 4px;
    font-size: 14px;
    opacity: 0;
    transition: opacity 0.3s;
    pointer-events: none;
  }

  .copy-notification.show {
    opacity: 1;
  }

  /* Media query for mobile devices */
  @media (min-width: 768px) {
    .container {
      flex-direction: row;
    }
    
    .editor-container, .preview-container {
      flex: 1;
    }
    
    .editor {
      border-bottom: none;
      border-right: 1px solid #ccc;
    }
    
    .toggle-button {
      display: none;
    }
  }

  @media (max-width: 767px) {
    .toggle-button {
      display: block;
    }
    
    .preview-container {
      display: none;
    }
    
    .editor-container {
      display: block;
    }
    
    .container.preview-mode .preview-container {
      display: block;
    }
    
    .container.preview-mode .editor-container {
      display: none;
    }

    .title {
      font-size: 1rem;
    }
  }
  </style>
<!-- inspired by https://htmledit.squarefree.com/ by Jesse Ruderman -->
</head>
<body>
  <div class="navbar">
    <h1 class="title">HTML Live Preview</h1>
    <div class="button-group">
      <button class="copy-button">Copy HTML</button>
      <button class="toggle-button">View Preview</button>
    </div>
  </div>
  
  <div class="container">
    <div class="editor-container">
      <textarea class="editor" spellcheck="false" autofocus></textarea>
    </div>
    
    <div class="preview-container">
      <iframe class="preview" sandbox="allow-scripts allow-same-origin"></iframe>
    </div>
  </div>

  <div class="copy-notification">HTML copied to clipboard!</div>

  <script type="module">
// Default content for the editor
const defaultContent = `<h3>Real-time HTML editor</h3>
<p>Enter HTML here and see a live preview as you type.</p>`;

// DOM elements
const editor = document.querySelector('.editor');
const preview = document.querySelector('.preview');
const toggleButton = document.querySelector('.toggle-button');
const copyButton = document.querySelector('.copy-button');
const copyNotification = document.querySelector('.copy-notification');
const container = document.querySelector('.container');

// Initialize editor with default content
editor.value = defaultContent;

// Create a blob URL for the iframe content
function createBlobURL(htmlContent) {
  const blob = new Blob([htmlContent], { type: 'text/html' });
  return URL.createObjectURL(blob);
}

// Update preview when editor content changes
function updatePreview() {
  try {
    // Create a new blob URL with the current HTML content
    const blobURL = createBlobURL(editor.value);
    
    // Set the iframe src to the new blob URL
    preview.src = blobURL;
    
    // Clean up the old blob URL when the iframe loads
    const oldURL = preview.dataset.blobURL;
    if (oldURL) {
      URL.revokeObjectURL(oldURL);
    }
    
    // Store the current blob URL for cleanup later
    preview.dataset.blobURL = blobURL;
  } catch (e) {
    console.error('Error updating preview:', e);
  }
}

// Copy HTML to clipboard
function copyToClipboard() {
  try {
    // Select the text
    editor.select();
    
    // Copy to clipboard
    navigator.clipboard.writeText(editor.value)
      .then(() => {
        // Show notification
        copyNotification.classList.add('show');
        
        // Hide notification after 2 seconds
        setTimeout(() => {
          copyNotification.classList.remove('show');
        }, 2000);
      })
      .catch(err => {
        console.error('Failed to copy text: ', err);
        // Fallback for older browsers
        document.execCommand('copy');
        copyNotification.classList.add('show');
        setTimeout(() => {
          copyNotification.classList.remove('show');
        }, 2000);
      });
      
    // Restore focus to editor
    setTimeout(() => {
      // Return to editing without interrupting workflow too much
      editor.focus();
    }, 50);
  } catch (err) {
    console.error('Failed to copy text: ', err);
  }
}

// Debounce function to prevent too many updates
function debounce(func, wait) {
  let timeout;
  return function() {
    clearTimeout(timeout);
    timeout = setTimeout(() => func(), wait);
  };
}

// Debounced update function (updates after 300ms of inactivity)
const debouncedUpdate = debounce(updatePreview, 300);

// Set up event listeners for editor changes
editor.addEventListener('input', debouncedUpdate);

// Initialize the preview when page loads
window.addEventListener('load', updatePreview);

// Toggle between editor and preview on mobile
toggleButton.addEventListener('click', () => {
  const isPreviewMode = container.classList.toggle('preview-mode');
  toggleButton.textContent = isPreviewMode ? 'View Editor' : 'View Preview';
});

// Handle resize events to reapply styles
window.addEventListener('resize', () => {
  // Force iframe to refresh its contents after resize
  updatePreview();
});

// Add click event listener for copy button
copyButton.addEventListener('click', copyToClipboard);
  </script>
</body>
</html>
